/******************************************************************
 *  MRRM's register file inside CPU                               *
 *                                                                *
 *  This file is part of the MRRM project                         *
 *  <http://mrrm.googlecode.com/>                                 *
 *                                                                *
 *  Author(s):                                                    *
 *    -  Yuan Pengfei <coolypf@opencores.org>                     *
 *                                                                *
 ******************************************************************
 *                                                                *
 *  Copyright (C) 2010 AUTHORS                                    *
 *                                                                *
 *  This source file may be used and distributed without          *
 *  restriction provided that this copyright statement is not     *
 *  removed from the file and that any derivative work contains   *
 *  the original copyright notice and the associated disclaimer.  *
 *                                                                *
 *  MRRM is free software: you can redistribute it and/or modify  *
 *  it under the terms of the GNU General Public License as       *
 *  published by the Free Software Foundation, either version 3   *
 *  of the License, or (at your option) any later version.        *
 *                                                                *
 *  MRRM is distributed in the hope that it will be useful, but   *
 *  WITHOUT ANY WARRANTY; without even the implied warranty of    *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the  *
 *  GNU General Public License for more details.                  *
 *                                                                *
 *  You should have received a copy of the GNU General Public     *
 *  License along with MRRM. If not, see                          *
 *  <http://www.gnu.org/licenses/>.                               *
 *                                                                *
 ******************************************************************/

`include "global.v"

module mrrm_rf(
	// Clock and reset
	clk, rst,
	// Write interface
	addrx, addry, datax, datay, wrx, wry,
	// Read interface
	addra, addrb, addrc, dataa, datab, datac
	);
	
parameter dw = `OPERAND_WIDTH;
parameter aw = `REGFILE_ADDR_WIDTH;

// Interfaces
// Clock and reset
input clk;
input rst;
// Write interface
input [aw-1:0] addrx;
input [aw-1:0] addry;
input [dw-1:0] datax;
input [dw-1:0] datay;
input wrx;
input wry;
// Read interface
input [aw-1:0] addra;
input [aw-1:0] addrb;
input [aw-1:0] addrc;
output [dw-1:0] dataa;
output [dw-1:0] datab;
output [dw-1:0] datac;

// Internal wires and regs
reg [32*dw-1:0] mem;
reg [dw-1:0] dataa;
reg [dw-1:0] datab;
reg [dw-1:0] datac;

// Write port X, Y
always @(posedge clk or `RST_EVENT rst)
	if(rst == `RST_VALUE) begin
		mem <= 1024'b0;
	end
	else begin
	if(wrx)
		case(addrx)
			5'd0: mem[32*0+31:32*0] <= datax;
			5'd1: mem[32*1+31:32*1] <= datax;
			5'd2: mem[32*2+31:32*2] <= datax;
			5'd3: mem[32*3+31:32*3] <= datax;
			5'd4: mem[32*4+31:32*4] <= datax;
			5'd5: mem[32*5+31:32*5] <= datax;
			5'd6: mem[32*6+31:32*6] <= datax;
			5'd7: mem[32*7+31:32*7] <= datax;
			5'd8: mem[32*8+31:32*8] <= datax;
			5'd9: mem[32*9+31:32*9] <= datax;
			5'd10: mem[32*10+31:32*10] <= datax;
			5'd11: mem[32*11+31:32*11] <= datax;
			5'd12: mem[32*12+31:32*12] <= datax;
			5'd13: mem[32*13+31:32*13] <= datax;
			5'd14: mem[32*14+31:32*14] <= datax;
			5'd15: mem[32*15+31:32*15] <= datax;
			5'd16: mem[32*16+31:32*16] <= datax;
			5'd17: mem[32*17+31:32*17] <= datax;
			5'd18: mem[32*18+31:32*18] <= datax;
			5'd19: mem[32*19+31:32*19] <= datax;
			5'd20: mem[32*20+31:32*20] <= datax;
			5'd21: mem[32*21+31:32*21] <= datax;
			5'd22: mem[32*22+31:32*22] <= datax;
			5'd23: mem[32*23+31:32*23] <= datax;
			5'd24: mem[32*24+31:32*24] <= datax;
			5'd25: mem[32*25+31:32*25] <= datax;
			5'd26: mem[32*26+31:32*26] <= datax;
			5'd27: mem[32*27+31:32*27] <= datax;
			5'd28: mem[32*28+31:32*28] <= datax;
			5'd29: mem[32*29+31:32*29] <= datax;
			5'd30: mem[32*30+31:32*30] <= datax;
			5'd31: mem[32*31+31:32*31] <= datax;
		endcase
	if(wry)
		case(addry)
			5'd0: mem[32*0+31:32*0] <= datay;
			5'd1: mem[32*1+31:32*1] <= datay;
			5'd2: mem[32*2+31:32*2] <= datay;
			5'd3: mem[32*3+31:32*3] <= datay;
			5'd4: mem[32*4+31:32*4] <= datay;
			5'd5: mem[32*5+31:32*5] <= datay;
			5'd6: mem[32*6+31:32*6] <= datay;
			5'd7: mem[32*7+31:32*7] <= datay;
			5'd8: mem[32*8+31:32*8] <= datay;
			5'd9: mem[32*9+31:32*9] <= datay;
			5'd10: mem[32*10+31:32*10] <= datay;
			5'd11: mem[32*11+31:32*11] <= datay;
			5'd12: mem[32*12+31:32*12] <= datay;
			5'd13: mem[32*13+31:32*13] <= datay;
			5'd14: mem[32*14+31:32*14] <= datay;
			5'd15: mem[32*15+31:32*15] <= datay;
			5'd16: mem[32*16+31:32*16] <= datay;
			5'd17: mem[32*17+31:32*17] <= datay;
			5'd18: mem[32*18+31:32*18] <= datay;
			5'd19: mem[32*19+31:32*19] <= datay;
			5'd20: mem[32*20+31:32*20] <= datay;
			5'd21: mem[32*21+31:32*21] <= datay;
			5'd22: mem[32*22+31:32*22] <= datay;
			5'd23: mem[32*23+31:32*23] <= datay;
			5'd24: mem[32*24+31:32*24] <= datay;
			5'd25: mem[32*25+31:32*25] <= datay;
			5'd26: mem[32*26+31:32*26] <= datay;
			5'd27: mem[32*27+31:32*27] <= datay;
			5'd28: mem[32*28+31:32*28] <= datay;
			5'd29: mem[32*29+31:32*29] <= datay;
			5'd30: mem[32*30+31:32*30] <= datay;
			5'd31: mem[32*31+31:32*31] <= datay;
		endcase
	end

// Read port A
always @(mem or addra)
	case(addra)
		5'd0: dataa = mem[32*0+31:32*0];
		5'd1: dataa = mem[32*1+31:32*1];
		5'd2: dataa = mem[32*2+31:32*2];
		5'd3: dataa = mem[32*3+31:32*3];
		5'd4: dataa = mem[32*4+31:32*4];
		5'd5: dataa = mem[32*5+31:32*5];
		5'd6: dataa = mem[32*6+31:32*6];
		5'd7: dataa = mem[32*7+31:32*7];
		5'd8: dataa = mem[32*8+31:32*8];
		5'd9: dataa = mem[32*9+31:32*9];
		5'd10: dataa = mem[32*10+31:32*10];
		5'd11: dataa = mem[32*11+31:32*11];
		5'd12: dataa = mem[32*12+31:32*12];
		5'd13: dataa = mem[32*13+31:32*13];
		5'd14: dataa = mem[32*14+31:32*14];
		5'd15: dataa = mem[32*15+31:32*15];
		5'd16: dataa = mem[32*16+31:32*16];
		5'd17: dataa = mem[32*17+31:32*17];
		5'd18: dataa = mem[32*18+31:32*18];
		5'd19: dataa = mem[32*19+31:32*19];
		5'd20: dataa = mem[32*20+31:32*20];
		5'd21: dataa = mem[32*21+31:32*21];
		5'd22: dataa = mem[32*22+31:32*22];
		5'd23: dataa = mem[32*23+31:32*23];
		5'd24: dataa = mem[32*24+31:32*24];
		5'd25: dataa = mem[32*25+31:32*25];
		5'd26: dataa = mem[32*26+31:32*26];
		5'd27: dataa = mem[32*27+31:32*27];
		5'd28: dataa = mem[32*28+31:32*28];
		5'd29: dataa = mem[32*29+31:32*29];
		5'd30: dataa = mem[32*30+31:32*30];
		5'd31: dataa = mem[32*31+31:32*31];
	endcase

// Read port B
always @(mem or addrb)
	case(addrb)
		5'd0: datab = mem[32*0+31:32*0];
		5'd1: datab = mem[32*1+31:32*1];
		5'd2: datab = mem[32*2+31:32*2];
		5'd3: datab = mem[32*3+31:32*3];
		5'd4: datab = mem[32*4+31:32*4];
		5'd5: datab = mem[32*5+31:32*5];
		5'd6: datab = mem[32*6+31:32*6];
		5'd7: datab = mem[32*7+31:32*7];
		5'd8: datab = mem[32*8+31:32*8];
		5'd9: datab = mem[32*9+31:32*9];
		5'd10: datab = mem[32*10+31:32*10];
		5'd11: datab = mem[32*11+31:32*11];
		5'd12: datab = mem[32*12+31:32*12];
		5'd13: datab = mem[32*13+31:32*13];
		5'd14: datab = mem[32*14+31:32*14];
		5'd15: datab = mem[32*15+31:32*15];
		5'd16: datab = mem[32*16+31:32*16];
		5'd17: datab = mem[32*17+31:32*17];
		5'd18: datab = mem[32*18+31:32*18];
		5'd19: datab = mem[32*19+31:32*19];
		5'd20: datab = mem[32*20+31:32*20];
		5'd21: datab = mem[32*21+31:32*21];
		5'd22: datab = mem[32*22+31:32*22];
		5'd23: datab = mem[32*23+31:32*23];
		5'd24: datab = mem[32*24+31:32*24];
		5'd25: datab = mem[32*25+31:32*25];
		5'd26: datab = mem[32*26+31:32*26];
		5'd27: datab = mem[32*27+31:32*27];
		5'd28: datab = mem[32*28+31:32*28];
		5'd29: datab = mem[32*29+31:32*29];
		5'd30: datab = mem[32*30+31:32*30];
		5'd31: datab = mem[32*31+31:32*31];
	endcase

// Read port C
always @(mem or addrc)
	case(addrc)
		5'd0: datac = mem[32*0+31:32*0];
		5'd1: datac = mem[32*1+31:32*1];
		5'd2: datac = mem[32*2+31:32*2];
		5'd3: datac = mem[32*3+31:32*3];
		5'd4: datac = mem[32*4+31:32*4];
		5'd5: datac = mem[32*5+31:32*5];
		5'd6: datac = mem[32*6+31:32*6];
		5'd7: datac = mem[32*7+31:32*7];
		5'd8: datac = mem[32*8+31:32*8];
		5'd9: datac = mem[32*9+31:32*9];
		5'd10: datac = mem[32*10+31:32*10];
		5'd11: datac = mem[32*11+31:32*11];
		5'd12: datac = mem[32*12+31:32*12];
		5'd13: datac = mem[32*13+31:32*13];
		5'd14: datac = mem[32*14+31:32*14];
		5'd15: datac = mem[32*15+31:32*15];
		5'd16: datac = mem[32*16+31:32*16];
		5'd17: datac = mem[32*17+31:32*17];
		5'd18: datac = mem[32*18+31:32*18];
		5'd19: datac = mem[32*19+31:32*19];
		5'd20: datac = mem[32*20+31:32*20];
		5'd21: datac = mem[32*21+31:32*21];
		5'd22: datac = mem[32*22+31:32*22];
		5'd23: datac = mem[32*23+31:32*23];
		5'd24: datac = mem[32*24+31:32*24];
		5'd25: datac = mem[32*25+31:32*25];
		5'd26: datac = mem[32*26+31:32*26];
		5'd27: datac = mem[32*27+31:32*27];
		5'd28: datac = mem[32*28+31:32*28];
		5'd29: datac = mem[32*29+31:32*29];
		5'd30: datac = mem[32*30+31:32*30];
		5'd31: datac = mem[32*31+31:32*31];
	endcase

endmodule
